import type { Draft } from 'immer';

import * as Types from './constants';
import type { IAction, IState } from './interface';

const eventMaps = new WeakMap();

class UpdateReducer {
  static of() {
    return new UpdateReducer();
  }

  constructor() {
    eventMaps.set(this, {});
  }

  on<P>(type: IAction['type'], callback: (draft: Draft<IState>, payload: P) => void) {
    eventMaps.get(this)[type] = callback;

    return this;
  }

  dispatch(draft: Draft<IState>, action: IAction) {
    const callback = eventMaps.get(this)[action.type];

    if (callback) {
      callback(draft, action.payload);
    }
  }
}

const updateReduce = UpdateReducer.of().on(
  Types.RESIZE,
  (draft, payload: Pick<IState, 'height' | 'width'>) => {
    const [originW, originH] = [1095, 1314];
    const percent = draft.radio / 100;

    const scaleX = payload.width / originW;
    const scaleY = payload.height / originH;
    const scale = Math.min(scaleX, scaleY);
    draft.width = Math.floor(originW * scale * percent);

    draft.height = Math.floor(originH * scale * percent);
    const offsetX = (payload.width - draft.width) / 2;
    const offsetY = (payload.height - draft.height) / 2;

    draft.canvasContentStyle = {
      opacity: 1,
      width: draft.width,
      height: draft.height,
      transform: `translate(${offsetX}px, ${offsetY}px)`
    };
  }
);

export default updateReduce;
